package com.syj.qdp.framework.redis.core.pubsub;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import com.syj.qdp.framework.common.util.json.JsonUtils;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;

import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
 * @author Lyon
 */
@Slf4j
public abstract class AbstractChannelMessageListener<T extends ChannelMessage> implements MessageListener {

    @Getter
    public String channel;
    private Class<T> messageType;

    public AbstractChannelMessageListener() {
        messageType = getMessageClass();
        channel = ReflectUtil.newInstance(messageType).getChannel();
    }

    @Override
    public void onMessage(Message message, byte[] bytes) {
        if (log.isDebugEnabled()) {
            try {
                log.debug("接收到[{}]消息:[{}]", StrUtil.str(message.getChannel(), StandardCharsets.UTF_8), StrUtil.str(message.getBody(), StandardCharsets.UTF_8));
            } catch (Exception e) {
                log.debug("记录消息日志失败");
            }
        }
        T data = JsonUtils.parseObject(message.getBody(), messageType);
        this.onMessage(data);
    }

    /**
     * 消息处理方法
     *
     * @param data
     */
    protected abstract void onMessage(T data);

    /**
     * 返回泛型的实际类型
     *
     * @return
     */
    private Class<T> getMessageClass() {
        Type typeArgument = TypeUtil.getTypeArgument(getClass(), 0);
        if (typeArgument == null) {
            throw new IllegalStateException(String.format("类型[%s] 需要正确的设置消息类型", getClass()));
        }
        return (Class<T>) typeArgument;
    }
}
